/*
 * transmission.c
 *
 * Created: 12/17/2012 12:17:26 PM
 *  Author: duerk@msoe.edu <Kevin Duer>
 *			zimmermane@msoe.edu <Evan Zimmerman>
 *			woottons@msoe.edu <Scott Wootton>
 *			
 * Purpose: to transmit data in the form of ASCII characters on the channel
 */ 

#include "transmission.h"			//header file for this class
#include<avr/io.h>					//i/o register definitions
#include<avr/interrupt.h>			//interrupt definitions
#include<stdint.h>					//for uint types

volatile uint8_t count = 16;
volatile uint16_t data = 0x0000;

/* initTX
 * 
 * Purpose: To initialize the the transmit functionality
 * Params: none
 * Returns: none
 */
void initTx(){
	DDRD |= OC2; //Set PD7 to be an output
	TCCR2 = (1<<CTC2)|(0<<PWM2); //CTC Mode without a prescaler
	//TCCR2 &= (~((1<<CS22)|(1<<CS21)|(1<<CS20))); //Turns the timer off
	//TCCR2 |= (0<<CS22)|(1<<CS21)|(1<<CS20); //Turns the timer on
	OCR2 = BIT_OVERFLOW;
	TIMSK |= (1<<OCIE2); //Enable Timer2 Output Compare
	TCNT2 = 0; //Reset the timer count
	count = 16; //Set the count to the max
	sei();
}

/* sendCharacter
 * 
 * Purpose: To send a character to the lcd
 * Params: char c - character to send
 * Returns: none
 */
void sendNetworkChar(char c){
	while(count < 16); //Wait until this is done transmitting
	data = 0x0000; //Clear the data
	int i;
	for(i = 0; i < 7; i++)
	{
		uint8_t encode;
		if((c>>i)&(0x01) == 1)
		{
			//1 transmitted
			encode = 0b00000001;
		} else {
			//0 Transmitted
			encode = 0x00000010;
		}
		//Shift the data by 1 and put the new bit at the end
		data = (data<<1) | encode;
	}
	TCCR2 |= (0<<CS22)|(1<<CS21)|(1<<CS20); //Turns the timer on, which causes interrupts
}

/* TIMER2_COMP_vect
 * 
 * Purpose: Used to transmit the data
 * Params: none
 * Returns: none
 */
ISR(TIMER2_COMP_vect){
	//Reset the timer
	TCNT2 = 0;
	PORTD = (((data>>count)&(0x0001))<<OC2); //Output the current bit and move it
	count++; //Increment the count
	//Check to see if the last bit was sent
	if(count >= 16)
	{
		//Reached the end so transmit a solid 1 and turn the timer off
		TCCR2 &= (~((1<<CS22)|(1<<CS21)|(1<<CS20))); //Turns the timer off
		PORTD =(1<<OC2); //Output a solid 1
		TCNT2 = 0; //Reset the count
	}
}